/**
 * 
 */
package com.google.code.jkippt;

import java.util.Collections;
import java.util.Map;

import com.google.code.jkippt.auth.Authentication;
import com.google.code.jkippt.http.APIClient;
import com.google.code.jkippt.http.HttpAPIClient;
import com.google.code.jkippt.http.ResourceEndpointUrlFactory;
import com.google.code.jkippt.parser.Parser;
import com.google.code.jkippt.resource.Account;

/**
 * The entry point for the API interaction.
 * @author Federico De Faveri defaveri@gmail.com
 */
public class JKippt {
	
	protected static final String ACCOUNT_ENDPOINT_NAME = "account";
	protected static final Map<String, String> INCLUDE_API_TOKEN_PARAMETERS = Collections.singletonMap("include_data", "api_token");

	protected Authentication authentication;
	protected APIClient client;
	protected Parser parser;
	protected ResourceEndpointUrlFactory accountEndpointUrlFactory = new ResourceEndpointUrlFactory(ACCOUNT_ENDPOINT_NAME);
	
	protected Users users;
	protected Clips clips;
	protected Lists lists;

	/**
	 * Creates a new {@link JKippt} class.
	 * @param authentication the authentication to use.
	 */
	public JKippt(Authentication authentication)
	{
		this.authentication = authentication;
		client = new HttpAPIClient(authentication);
		parser = new Parser();
	}
	
	public JKippt(APIClient client)
	{
		this.client = client;
		parser = new Parser();
	}

	/**
	 * Returns the user account.
	 * @return the user account.
	 * @throws JKipptException if an error occurs.
	 */
	public Account getAccount() throws JKipptException
	{
		return getAccount(false);
	}
	
	/**
	 * Returns the user account.
	 * @param includeApiToken if the account should include the API Token.
	 * @return the user account.
	 * @throws JKipptException if an error occurs.
	 */
	public Account getAccount(boolean includeApiToken) throws JKipptException
	{
		String endpoint = accountEndpointUrlFactory.buildEndpointUrl(includeApiToken?INCLUDE_API_TOKEN_PARAMETERS:ResourceEndpointUrlFactory.NO_PARAMETERS);
		String json = client.get(endpoint);
		return parser.parseAccount(json);
	}
	
	/**
	 * Returns the {@link Users} endpoint that manages user related requests.
	 * @return the {@link Users} endpoint.
	 */
	public Users users()
	{
		if (users == null) users = new Users(client, parser);
		return users;
	}
	

	/**
	 * Returns the {@link Clips} enpoint.
	 * @return the {@link Clips} endpoint.
	 */
	public Clips clips()
	{
		if (clips == null) clips = new Clips(client, parser);
		return clips;
	}
	
	/**
	 * Returns the {@link Lists} endpoint.
	 * @return the {@link Lists} endpoint.
	 */
	public Lists lists()
	{
		if (lists == null) lists = new Lists(client, parser);
		return lists;
	}

}
